package com.icloud.cer.rest.web.action;

import java.util.ArrayList;
import java.util.List;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import org.apache.log4j.Logger;
import org.apache.mina.core.session.IoSession;

import com.icloud.cer.rest.common.BizException;
import com.icloud.cer.rest.common.ContextHolder;
import com.icloud.cer.rest.common.MessageCode;
import com.icloud.cer.rest.msg.bean.ClientView;
import com.icloud.cer.rest.util.ApplicationContextHelper;
import com.icloud.cer.rest.util.ConnectorManager;
import com.icloud.cer.rest.util.StringUtils;
import com.icloud.cer.rest.web.bean.EncryptResult;
import com.icloud.cer.rest.web.bean.EncryptorStatus;
import com.icloud.cer.rest.web.bean.ServerStatus;
import com.icloud.cer.rest.web.bean.TaskInfo;
import com.icloud.cer.rest.web.service.EncryptService;



@Path("/encrypt")
public class EncryptAction {
	private Logger log = Logger.getLogger(EncryptAction.class);
	
	public EncryptAction(){
		
	}
	
	@GET
    @Path("{userId}/{certification}")
    @Produces({MediaType.APPLICATION_JSON})
    public EncryptResult doEncrypt(@PathParam("userId") String userId,@PathParam("certification") String certification) {
		log.debug("userId:" + userId);
		log.debug("cer:" + certification );
		EncryptService encryptService = ApplicationContextHelper.getBean("encryptService");
		EncryptResult result = null;
		try {
			result = encryptService.doEncrypt(userId, certification);
		} catch (BizException e) {
			String errMsg = e.getFormattedMessage(ContextHolder.getSessionLocale());
			result = new EncryptResult();
			result.setErrorCode(e.getCode());
			result.setErrorMessage(errMsg);
			log.error(errMsg);
		} catch (Exception e) {
			result = new EncryptResult();
			result.setErrorCode(MessageCode.E10000);
			result.setErrorMessage(StringUtils.getTrace(e));
			log.error(result.getErrorMessage());
		}
		return result;
    }
	
	@GET
    @Path("serverStatus/{serverId}")
    @Produces({MediaType.APPLICATION_JSON})
	 public ServerStatus  getServerStatus(@PathParam("serverId") String serverId) {
		log.debug("serverId:" + serverId);
		EncryptService encryptService = ApplicationContextHelper.getBean("encryptService");
		ServerStatus status = null;
		try {
			status = encryptService.getServerStatus(serverId);
		} catch (BizException e) {
			String errMsg = e.getFormattedMessage(ContextHolder.getSessionLocale());
			status = new ServerStatus();
			status.setErrorCode(e.getCode());
			status.setErrorMessage(errMsg);
			log.error(errMsg);
		} catch (Exception e) {
			status = new ServerStatus();
			BizException be = new BizException(MessageCode.E10003, StringUtils.getTrace(e));
			String errMsg = be.getFormattedMessage(ContextHolder.getSessionLocale());
			status.setErrorCode(MessageCode.E10002);
			status.setErrorMessage(errMsg);
			log.error(errMsg);
		}
		return status;
	}
	
	@GET
    @Path("encryptorStatus/{encryptorId}")
    @Produces({MediaType.APPLICATION_JSON})
	 public EncryptorStatus  getEncryptorStatus(@PathParam("encryptorId") String encryptorId) {
		log.debug("encryptorId:" + encryptorId);
		EncryptService encryptService = ApplicationContextHelper.getBean("encryptService");
		EncryptorStatus status = null;
		try {
			status = encryptService.getEncryptorStatus(encryptorId);
		} catch (BizException e) {
			String errMsg = e.getFormattedMessage(ContextHolder.getSessionLocale());
			status = new EncryptorStatus();
			status.setErrorCode(e.getCode());
			status.setErrorMessage(errMsg);
			log.error(errMsg);
		} catch (Exception e) {
			status = new EncryptorStatus();
			BizException be = new BizException(MessageCode.E10003, StringUtils.getTrace(e));
			String errMsg = be.getFormattedMessage(ContextHolder.getSessionLocale());
			status.setErrorCode(MessageCode.E10003);
			status.setErrorMessage(errMsg);
			log.error(errMsg);
		}
		return status;
	}
	
	@GET
    @Path("taskInfo")
    @Produces({MediaType.APPLICATION_JSON})
	public List<TaskInfo>  getTaskInfo() {
		ConnectorManager connectorManager = ApplicationContextHelper.getBean("connectorManager");
		ConcurrentHashMap<Long, AtomicInteger> taskMap = connectorManager.getTaskCountMap();
		List<TaskInfo> tasks = new ArrayList<TaskInfo>();
		for(Entry<Long, AtomicInteger> entry : taskMap.entrySet()) {
			TaskInfo t = new TaskInfo();
			tasks.add(t);
			Long key = entry.getKey();
			t.setSessionId(key.toString());
			AtomicInteger count = entry.getValue();
			if(count == null) {
				t.setWaitCount(0);
			} else {
				t.setWaitCount(count.get());
			}
			ClientView clientView = connectorManager.getClientView(key);
			if(clientView == null) {
				t.setErrorMsg("can not get client.properly session is closed.");
				continue;
			}
			t.setEncryptorId(clientView.getEncryptorId());
		}
		if(tasks.isEmpty()) {
			List<ClientView>  cvs = connectorManager.getAllClient();
			List<IoSession> sessions = connectorManager.getAllSessions();
			if(cvs.isEmpty() || sessions.size() == 0) {
				TaskInfo t = new TaskInfo();
				t.setErrorMsg("no client connect to server.");
				tasks.add(t);
				return tasks;
			}
			for(IoSession s : sessions) {
				long sessionId = s.getId();
				TaskInfo t = new TaskInfo();
				tasks.add(t);
				t.setSessionId(String.valueOf(sessionId));
				ClientView cv = connectorManager.getClientView(sessionId);
				if(cv == null) {
					t.setErrorMsg("can not get client.properly session is closed.");
					continue;
				}
				t.setEncryptorId(t.getEncryptorId());
				AtomicInteger count = taskMap.get(sessionId);
				if(count == null) {
					t.setWaitCount(0);
				} else {
					t.setWaitCount(count.get());
				}
			}
		}
			
		return tasks;
	}
}
